package cn.qiao.fs;
 
import cn.qiao.fs.esl.transport.message.EslMessage;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import lombok.extern.slf4j.Slf4j;
 
import java.nio.charset.Charset;
@Slf4j
public class NettyClient {
    /**
     * 建立连接后的操作：
     * 方法一：用sync()方法。
     */
    public void fun(ChannelFuture channelFuture) throws InterruptedException {
        /**
         * 如果连接还没有建立好就无法获取Channel，因此，有了sync()方法，
         * 作用是阻塞等到连接建立好程序才向下运行。
         */
        channelFuture.sync();
        Channel channel = channelFuture.channel();
        //打印main线程
        log.info("channel==========={}",channel);
        //向服务器发送数据
        channel.writeAndFlush("Hello world!");
    }
    /**
     * 建立连接后的操作：
     * 方法二：用addListener()方法。异步调用回调对象的operationComplete方法。
     */
    public void fun2(ChannelFuture channelFuture) throws InterruptedException {
        //把ChannelFutureListener对象传递给EventLoopGroup线程，EventLoopGroup线程建立好连接以后调用operationComplete方法。
        channelFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                Channel channel = channelFuture.channel();
                //打印nioEventLoopGroup线程
                log.info("channel==========={}",channel);
                //向服务器发送数据
                channel.writeAndFlush("Hello world!");
            }
        });
    }
 
    public static void main(String[] args) throws InterruptedException {
        //启动Netty客户端
        Bootstrap bootstrap = new Bootstrap();
        //选择EventLoop
        bootstrap.group(new NioEventLoopGroup());
        //选择客户端Channel实现，Channel是数据的传输通道。
        bootstrap.channel(NioSocketChannel.class);
        //添加处理器，
        bootstrap.handler(new ChannelInitializer<NioSocketChannel>() {
            //连接建立后初始化Channel
            @Override
            protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                //把字符串编码成ByteBuf
                nioSocketChannel.pipeline().addLast(new StringEncoder(Charset.forName("UTF-8")));
                nioSocketChannel.pipeline().addLast("clientHandler", new SimpleChannelInboundHandler<EslMessage>(){

                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx, EslMessage message) throws Exception {
                        System.out.println(message);
                        System.out.println(ctx);
                    }
                });
            }
        });
        /**
         * Netty客户端和服务端建立连接是由EventLoopGroup线程负责的，而不是由main线程负责的。
         * 因此，这个建立连接的过程是异步非阻塞操作。
         */
        ChannelFuture channelFuture = bootstrap.connect("localhost", 8021);
 
        //new NettyClient().fun( channelFuture);
 
        new NettyClient().fun2( channelFuture);
    }
}